#ifndef __HARDIIC_H
#define __HARDIIC_H

#include "STC8G.h"
#include "delay.h"
#define EAXFR 0x80 //I2C功能寄存器为扩展 SFR，逻辑地址位于 XDATA 区域，访问前需要将 P_SW2（BAH）寄存器的最高位（EAXFR）置 1

void hardiic_init();
void hardiic_read_nbyte(uchar device_addr, uchar reg_addr, uchar *p, uchar number);
void hardiic_write_nbyte(uchar device_addr, uchar reg_addr, uchar *p, uchar number);
/************************************************************************
 *
 *                         以下代码由STC-ISP直接生成
 * 
************************************************************************/
//========================================================================
// 描述: 等待以及清除中断标志位.
// 参数: none.
// 返回: none.
//========================================================================
void Wait()
{
    while (!(I2CMSST & 0x40))
        ;
    I2CMSST &= ~0x40;
}
//========================================================================
// 描述: IIC发送start信号.
// 参数: none.
// 返回: none.
//========================================================================
void Start()
{
    I2CMSCR = 0x01; //发送START命令
    Wait();
}
//========================================================================
// 描述: IIC发送一个字节数据.
// 参数: 发送的字节数据.
// 返回: none.
//========================================================================
void SendData(char dat)
{
    I2CTXD = dat;   //写数据到数据缓冲区
    I2CMSCR = 0x02; //发送SEND命令
    Wait();
}
//========================================================================
// 描述: IIC等待ack信号.
// 参数: none.
// 返回: none
//========================================================================
void RecvACK()
{
    I2CMSCR = 0x03; //发送读ACK命令
    Wait();
}
//========================================================================
// 描述: IIC读取一个字节数据.
// 参数: none
// 返回: 读取到的字节数据.
//========================================================================
char RecvData()
{
    I2CMSCR = 0x04; //发送RECV命令
    Wait();
    return I2CRXD;
}
//========================================================================
// 描述: IIC发送ack信号.
// 参数: none.
// 返回: none.
//========================================================================
void SendACK()
{
    I2CMSST = 0x00; //设置ACK信号
    I2CMSCR = 0x05; //发送ACK命令
    Wait();
}
//========================================================================
// 描述: IIC发送NAck信号.
// 参数: none.
// 返回: none.
//========================================================================
void SendNAK()
{
    I2CMSST = 0x01; //设置NAK信号
    I2CMSCR = 0x05; //发送ACK命令
    Wait();
}
//========================================================================
// 描述: IIC发送stop信号.
// 参数: none.
// 返回: none.
//========================================================================
void Stop()
{
    I2CMSCR = 0x06; //发送STOP命令
    Wait();
}
//========================================================================
// 描述: 短延时.
// 参数: none.
// 返回: none.
//========================================================================
void Delay()
{
    int i;

    for (i = 0; i < 3000; i++)
    {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    }
}

//========================================================================
// 描述: IIC初始化.
// 参数: none.
// 返回: none.
//========================================================================
void hardiic_init(uchar num)
{
    uchar temp = 0x00;
    switch (num)
    {
    case 1:
        P1M0 = 0x00;
        P1M1 = 0x00;
        temp |= 0x00; //0000 0000 I2C_S0=0 I2C_S1=0 (P1.5/SCL, P1.4/SDA)
        break;
    case 2: //stc8g没有
        P2M0 = 0x00;
        P2M1 = 0x00;
        temp |= 0x20; //0010 0000 I2C_S0=1 I2C_S1=0 (P2.5/SCL, P2.4/SDA)
        break;
    case 3: //stc8g没有
        P7M0 = 0x00;
        P7M1 = 0x00;
        temp |= 0x10; //0001 0000 I2C_S0=0 I2C_S1=1(P7.7/SCL, P7.6/SDA)
        break;
    case 4:
        P3M0 = 0x00;
        P3M1 = 0x00;
        temp |= 0x30; //0011 0000 I2C_S0=1 I2C_S1=1 (P3.2/SCL, P3.3/SDA)
        break;
    default:
        break;
    }
    temp |= EAXFR;
    P_SW2 = temp;
    I2CCFG = 0xe0;  //使能IIC主机模式
    I2CMSST = 0x00; //IIC主机状态寄存器清零
}

//========================================================================
// 描述: IIC读取n个字节数据.
// 参数: 设备地址（8位模式，7位地址需要左移一位），寄存器地址，缓存数据地址，数量
// 返回: none.
//========================================================================
void hardiic_read_nbyte(uchar device_addr, uchar reg_addr, uchar *p, uchar number)
{
    Start();               //开始信号
    SendData(device_addr); //发送器件写地址
    RecvACK();
    SendData(reg_addr); //发送寄存器地址
    RecvACK();

    Start();                      //重复开始信号
    SendData(device_addr | 0x01); //发送器件读地址
    RecvACK();
    do
    {
        *p = RecvData();
        p++;
        if (number != 1)
            SendACK();

    } while (--number);
    SendNAK();
    Stop();
}

//========================================================================
// 描述: IIC写n个字节数据.
// 参数: 设备地址（8位模式，7位地址需要左移一位），寄存器地址，缓存数据地址，数量
// 返回: none.
//========================================================================
void hardiic_write_nbyte(uchar device_addr, uchar reg_addr, uchar *p, uchar number)
{
    Start();               //开始信号
    SendData(device_addr); //发送器件写地址
    RecvACK();
    SendData(reg_addr); //发送寄存器地址
    RecvACK();
    do
    {
        SendData(*p++); //发送数据
        RecvACK();
    } while (--number);
    Stop(); //发送停止命令
}

#endif //hardiic                                                                     \
